home *** CD-ROM | disk | FTP | other *** search
- ;*************************************************************************
- ;** mmu.library **
- ;** **
- ;** a system library for arbitration and control of the MC68K MMUs **
- ;** **
- ;** © 1998 THOR-Software, Thomas Richter **
- ;** No commercial use, reassembly, modification without prior, written **
- ;** permission of the authors. **
- ;** Including this library in any commercial software REQUIRES a **
- ;** written permission and the payment of a small fee. **
- ;** **
- ;** This is an internal header file, do not depend on anything here. **
- ;** Use the official include files. **
- ;** Distributed only for the mmu.library development group for private **
- ;** use. **
- ;** **
- ;**---------------------------------------------------------------------**
- ;** Block: The library base **
- ;** Initializisation and basic jump vectors of the mmu.library **
- ;*************************************************************************
-
- ;FOLD Includes
- include INC:macros.asm
- include mu_lib.i
- include mu_version.i
- include mu_alerts.i
- include mu_context.i
- include kaputstr.i
-
- ;we include just the offsets.
- ;I personally hate to write _LVO all the time, this is stripped
- ;in this file.
- include INC:exec_lib.asm
- ;ENDFOLD
- ;FOLD External References
- xref DetectMMUType
- xref AllocAligned
- xref MUCreatePool
- xref MUDeletePool
- xref AllocContext
- xref BuildDefaultTable
- xref LockContext
- xref UnlockContext
- xref AllocContextMem
- xref FreeContextMem
- xref FreeContext
- xref SetGlobal
- xref BuildMMUTable
- xref ParseMMUTable
-
- xref Init851
- xref Init030
- xref Init040
- xref Init060
- ;ENDFOLD
- ;FOLD Defines
- ;I'm again too lazy to include the complete exec/execbase.i.
- ;Here just what I need:
- AttnFlags = $128
- ;ENDFOLD
-
- section main_code,code
-
- ;FOLD DOS Entry
- ;*************************************************
- ;** DOS Entry **
- ;** Since this is not supposed to be executable,**
- ;** we return -1. This is an indicator for the **
- ;** shell not to execute it. **
- ;*************************************************
- DosEntry:
- moveq #-1,d0
- rts
- ;ENDFOLD
- ;FOLD Resident
- ;*************************************************
- ;** Resident **
- ;** the resident structure of this library **
- ;** used for the autoinit function **
- ;*************************************************
- Resident:
- dc.w $4afc ;MatchWord
- dc.l Resident ;Back pointer
- dc.l 0 ;no endskip
- dc.b $80 ;add to the system, do not jump in
- dc.b Version ;version nummer
- dc.b NT_LIBRARY ;this is a library
- dc.b 0 ;priority
- dc.l MMUName ;name of the library
- dc.l IDString ;ID string
- dc.l Init ;pointer to the init data
-
- section main_data,data ;we continue in the data
- ;segment for consitency
- Init:
- dc.l mulib_len ;size of the library
- dc.l FuncInit ;jump vector init data, below
- dc.l 0 ;no structinit. I can't stand this mess
- dc.l LibInit ;library init vector
- ;ENDFOLD
- ;FOLD FuncInit
- ;*************************************************
- ;** FuncInit **
- ;** Library jump vector inits **
- ;*************************************************
- FuncInit:
- dc.l OpenMULib
- dc.l CloseMULib
- dc.l ExpungeMULib
- dc.l ExtFunc ;Extended function, unused
-
- ;Library functions follow here
- dc.l AllocAligned
- dc.l GetMapping
- dc.l ReleaseMapping
- dc.l GetPageSize
- dc.l GetMMUType
-
- dc.l GetMMUConfig
- dc.l ReleaseMMUConfig
-
- dc.l -1
- ;ENDFOLD
-
- section main_code,code
-
- ;FOLD Stub routines, reserved routines etc.
- opt c+
- xdef ___stub
- ___stub:
- opt c-
- ExtFunc:
- ReservedVector:
- moveq #0,d0
- rts
- ;ENDFOLD
-
- ;FOLD MUAlert
- ;*************************************************
- ;** Alert routine **
- ;** Alerts with the alert ID on the stack **
- ;** this long word is removed automagically **
- ;*************************************************
- xdef MUAlert
- MUAlert:
- saveregs d0-d1/d7/a0-a1/a5-a6
- move.l $20(a7),d7 ;get alert code
- move.l mulib_CurrentContext(a6),a5 ;this as parameter
- move.l mulib_SysBase(a6),a6
- jsr Alert(a6)
- loadregs
- move.l (a7)+,(a7)
- rts
- ;ENDFOLD
-
- ;FOLD LibInit
- ;*************************************************
- ;** LibInit **
- ;** the Library Init vector **
- ;** we're called like this: **
- ;** Library base in d0, ExecBase in a6 **
- ;** BPTR segment in a0 **
- ;** **
- ;** We must return the initialized library base **
- ;** in d0, or NULL in case of a failure **
- ;*************************************************
- LibInit:
- saveregs d2/a4/a6
-
- move.l d0,a4
-
- kaputstr <"Library base is %lx, ExecBase is %lx">,a4,a6
-
- move.l a6,mulib_SysBase(a4) ;keep SysBase
- move.l a0,mulib_Segment(a4)
- move.b 1+AttnFlags(a6),mulib_AttnFlags(a4) ;copy AttnFlags
-
- move.b #NT_LIBRARY,mulib_type(a4) ;type is library
- move.b #(1<<lib_changed)!(1<<lib_sumused),mulib_flags(a4) ;library flags
- move.l #MMUName,mulib_name(a4)
- move.l #IDString,mulib_idstring(a4)
- move.l #PackedVersion,mulib_version(a4) ;Version, Revision at once
-
- lea mulib_ContextList(a4),a0
- NewList a0 ;initialize the context list
-
- ;initialize the semaphores
- lea mulib_ContextSemaphore(a4),a0
- jsr InitSemaphore(a6)
- lea mulib_PoolSemaphore(a4),a0
- jsr InitSemaphore(a6)
-
- btst #AF_68040,mulib_AttnFlags(a4) ;no need to bother ramlib
- beq.s .donttry
-
- lea MC68040Name,a1
- moveq #0,d0
- jsr OpenLibrary(a6)
- move.l d0,mulib_040Base(a4)
-
- lea MC68060Name,a1
- moveq #0,d0
- jsr OpenLibrary(a6)
- move.l d0,mulib_060Base(a4)
-
- .donttry:
- lea ExpansionName,a1
- moveq #37,d0
- jsr OpenLibrary(a6)
- move.l d0,mulib_ExpansionBase(a4)
- beq .noexpansion
-
- lea UtilityName,a1
- moveq #37,d0 ;Version 37 minimum
- jsr OpenLibrary(a6)
- move.l d0,mulib_UtilityBase(a4)
- beq .noutility ;exit on failure
-
- move.l a4,a6
-
- move.l #$1,d0 ;MEMF_PUBLIC
- move.l #(map_len+4)*32,d1 ;puddle size related to mapping structures
- move.l #(map_len+4)*4,d2 ;puddle threshold
- bsr MUCreatePool ;create the memory pool
- move.l d0,mulib_ContextPool(a4)
- beq .nomemory
-
- bsr DetectMMUType ;read MMU type
- ifd fake040
- moveq #mutype_68040,d0
- endc
- ifd fake060
- moveq #mutype_68060,d0
- endc
- move.b d0,mulib_MMUType(a4)
-
- lea NOP(pc),a0
- lea mulib_Internals(a4),a1
- for.l #mulib_InternalVecs,d1
- move.w #$4ef9,(a1)+ ;Jmp
- move.l a0,(a1)+ ;to NOP
- next d1
-
- lea mulib_Internals(a4),a1
- move.l a4,a6
- lea Init851(pc),a0 ;now initialize MMU specific stuff
- cmp.b #mutype_68851,d0
- beq.s .initme
-
- lea Init030(pc),a0
- cmp.b #mutype_68030,d0
- beq.s .initme
-
- lea Init040(pc),a0
- cmp.b #mutype_68040,d0
- beq.s .initme
-
- lea Init060(pc),a0
- cmp.b #mutype_68060,d0
- bne.s .nommu ;no known MMU here!
- .initme:
- jsr (a0) ;jump to the init vector of this MMU
- tst.l d0 ;did work?
- beq .alertnommu
- .nommu:
- move.l mulib_SysBase(a4),a6
- jsr CacheClearU(a6) ;Flush the initialized vectors
-
- move.l a4,a6
-
- lea mulib_MMUConfig(a4),a0
- jsr mulib_ReadConfig(a6) ;read MMU configuration, keep it for later
-
- moveq #-1,d0
- move.l d0,mulib_RootMask(a4)
-
- lea mulib_MMUConfig(a4),a0
- jsr mulib_SetLibrary(a6)
-
- bsr SetupMasks
-
- bsr AllocContext ;allocate a context structure for the global stuff
- move.l d0,mulib_DefaultContext(a4) ;build default context
- beq.s .quitpool
-
- move.l d0,a0
- bsr BuildDefaultTable ;define default mapping
- tst.l d0
- beq.s .quitpool ;failure
-
- lea mulib_MMUConfig(a4),a1
- move.l mulib_DefaultContext(a4),a0
- bsr ParseMMUTable ;scan the MMU table
- tst.l d0
- beq.s .quitpool
-
- lea mulib_MMUConfig(a4),a1
- move.l mulib_DefaultContext(a4),a0
- jsr mulib_ParseTT(a6) ;scan the transparent translation
- tst.l d0
- beq.s .quitpool
-
- move.l mulib_DefaultContext(a4),a0 ;get again this context
- bsr SetGlobal ;make this global
-
- move.l mulib_DefaultContext(a4),a0
- ;bsr BuildMMUTable ;build the table for this context
- ;beq.s .quitpool
-
- move.l mulib_DefaultContext(a4),a1
- lea mulib_ContextList(a4),a0
- AddHead ;add this at the start of the list
-
- bra .exit ;initialization done
- .alertnommu: ;no need to release the
- pea AN_MMUInit ;context. Done automatically
- bsr MUAlert
-
- .quitpool:
- move.l mulib_ContextPool(a4),a0
- bsr MuDeletePool
- ;bra.s .closeutility
-
- .nomemory:
- ;pea AN_NoPoolMem
- ;bsr MUAlert
-
- .closeutility:
- move.l mulib_SysBase(a4),a6
- move.l mulib_UtilityBase(a4),a1
- jsr CloseLibrary(a6)
- clr.l mulib_UtilityBase(a4)
- bra.s .overu
- .noutility:
- pea AN_NoUtility
- bsr MUAlert
- .overu:
- move.l mulib_SysBase(a4),a6
- move.l mulib_ExpansionBase(a4),a1
- jsr CloseLibrary(a6)
- clr.l mulib_ExpansionBase(a4)
- bra.s .overe
-
- .noexpansion:
- pea AN_NoExpansion
- bsr MUAlert
- .overe:
- move.l mulib_SysBase(a4),a6
- move.l mulib_040Base(a4),d0
- beq.s .no040
- move.l d0,a1
- jsr CloseLibrary(a6)
- .no040:
- move.l mulib_060Base(a4),d0
- beq.s .no060
- move.l d0,a1
- jsr CloseLibrary(a6)
- .no060:
-
- .failure: ;in case of a failure,
- ;we've to cleanup ourselves
- move.l mulib_SysBase(a4),a6
- move.l a4,a1
- moveq #0,d0
- moveq #0,d1
- move.w mulib_negsize(a4),d0
- move.w mulib_possize(a4),d1
- sub.l d0,a1 ;*Mem
- add.l d1,d0 ;length
- jsr FreeMem(a6) ;release memory
-
- sub.l a4,a4 ;tough luck
- .exit:
- move.l a4,d0
- loadregs
- rts
- NOP:
- moveq #0,d0
- rts
- ;ENDFOLD
- ;FOLD OpenMULib
- ;*************************************************
- ;** OpenMULib **
- ;** Open the MMU library **
- ;*************************************************
- OpenMULib:
- bclr #lib_delexp,mulib_flags(a6) ;clear the delayed expunge flag
- addq.w #1,mulib_opencnt(a6) ;increment the open counter
- move.l a6,d0 ;that's it
- rts
- ;ENDFOLD
- ;FOLD CloseMULib
- ;*************************************************
- ;** CloseMULib **
- ;** Close the MMU library again **
- ;*************************************************
- CloseMULib:
- tst.w mulib_opencnt(a6)
- beq.s .ignore
- subq.w #1,mulib_opencnt(a6) ;Decrement open counter
- btst #lib_delexp,mulib_flags(a6) ;Delayed expunge active ?
- bne.s ExpungeMULib
- .ignore:
- moveq #0,d0 ;do not quit
- rts
- ;ENDFOLD
- ;FOLD ExpungeMULib
- ;*************************************************
- ;** ExpungeMULib **
- ;** Remove the MMU library from memory, if **
- ;** possible **
- ;*************************************************
- ExpungeMULib:
- bset #lib_delexp,mulib_flags(a6) ;delay at least
- moveq #0,d0 ;do not flush
- tst.w mulib_opencnt(a6) ;still in use?
- bne .exit
- btstm mmuf1_contextopen,mulib_flags1(a6) ;still an open context?
- beq.s .flush
- ;here yes. Something went extremly wrong
- pea AN_ContextOpen
- bsr MUAlert ;Create a guru
- moveq #0,d0 ;do not quit
- bra .exit
- .flush:
- saveregs a4
- move.l a6,a4
- ;restore the vector base
-
- move.l a6,a1
- Remove ;Remove the library from the system list
-
- move.l mulib_DefaultContext(a6),a1
- Remove ;Remove this Context
-
- lea mulib_MMUConfig(a6),a0
- jsr mulib_WriteConfig(a6) ;restore original MMU data
-
- move.l mulib_DefaultContext(a6),a0
- bclrm ctxf_active,ctx_Flags(a0) ;deactivate the context by
- ;brute force. The MMU has been reloaded by the call above
- bsr FreeContext ;release it and the tables
-
-
- move.l mulib_ContextPool(a6),a0
- bsr MUDeletePool ;release the memory pool. Releases the context as well and the context mapping
-
- move.l mulib_SysBase(a6),a6
-
- move.l mulib_UtilityBase(a4),d0
- beq.s .noutility
- move.l d0,a1
- jsr CloseLibrary(a6)
- .noutility:
- move.l mulib_ExpansionBase(a4),d0
- beq.s .noexpansion
- move.l d0,a1
- jsr CloseLibrary(a6)
- .noexpansion:
- move.l mulib_060Base(a4),d0
- beq.s .no60
- move.l d0,a1
- jsr CloseLibrary(a6)
- .no60:
- move.l mulib_040Base(a4),d0
- beq.s .no40
- move.l d0,a1
- jsr CloseLibrary(a6)
- .no40:
-
- move.l mulib_Segment(a4),-(a7) ;Saveback the segment
- move.l a4,a1 ;->Base Mem
- moveq #0,d0
- moveq #0,d1
- move.w mulib_negsize(a1),d0 ;NegSize->d0
- move.w mulib_possize(a1),d1 ;Possize->d1
- sub.l d0,a1 ;*Mem
- add.l d1,d0 ;mem total
- jsr FreeMem(a6) ;release
-
- move.l (a7)+,d0 ;restore segment
- loadregs
- .exit:
- rts
- ;ENDFOLD
-
- ;FOLD SetupMasks
- ;*************************************************
- ;** SetupMasks **
- ;** use the data filled in by the MMU setup **
- ;** codes to build all the mask and bit **
- ;** lookup tables we need **
- ;*************************************************
- SetupMasks:
- saveregs d2-d5/a2-a5
-
- moveq #-1,d1
- moveq #1,d2
- move.l #4,mulib_IndirectAlign(a6) ;this is fixed
- lea mulib_LevelAAlign(a6),a5
- lea mulib_LevelAMask(a6),a4
- lea mulib_LevelATableSz-4(a6),a3
- lea mulib_LevelAPos-1(a6),a2
- lea mulib_LevelASize-4(a6),a1
- lea mulib_LevelABits-1(a6),a0
- moveq #0,d3
- do
- move.b (a0)+,d0 ;bits for this level
- beq.s .noshift
- ror.l d0,d2 ;calculate size of the pages at this level
- .noshift:
- move.b d3,(a2)+ ;the starting bit position within the address at this level
- moveq #0,d4
- add.b d0,d3 ;add up the bits
- move.l (a5)+,d5 ;read the alignment restrictions
- bset d0,d4 ;the number of entries at this level
- neg.l d5 ;calculate a mask from that
- move.l d2,d0 ;keep the page size
- move.l d5,(a4)+ ;enter the mask
- and.b #$fe,d0 ;bit 0 might not yet have been shifted out
- move.l d4,(a3)+ ;insert the number of entries for a table at this level
- addq.w #1,d1 ;increment the counter
- move.l d0,(a1)+ ;insert the page size
- cmp.w #4,d1 ;until done
- while.s ls
-
- loadregs
- rts
- ;ENDFOLD
-
- ;** Function entries
-
- ;FOLD GetMapping
- ;*************************************************
- ;** GetMapping **
- ;** get for the ctx *a0 or the default ctx **
- ;** if *a0==NULL the mapping. Lock the context **
- ;*************************************************
- GetMapping:
- move.l a0,d0
- bne.s .nodefault
- move.l mulib_DefaultContext(a6),a0
- .nodefault:
- bsr LockContext
-
- lea ctx_Mapping(a0),a0
- move.l a0,d0
- rts
- ;ENDFOLD
- ;FOLD ReleaseMapping
- ;*************************************************
- ;** ReleaseMapping **
- ;** release the mapping of context *a0 **
- ;** or the default context if NULL **
- ;*************************************************
- ReleaseMapping:
- move.l a0,d0
- bne.s .nodefault
- move.l mulib_DefaultContext(a6),a0
- .nodefault:
- bsr UnlockContext
- rts
- ;ENDFOLD
- ;FOLD GetPageSize
- ;*************************************************
- ;** GetPageSize **
- ;** Return the page size of the MMU **
- ;*************************************************
- GetPageSize:
- move.l mulib_PageSize(a6),d0
- rts
- ;ENDFOLD
- ;FOLD GetMMUType
- ;*************************************************
- ;** GetMMUType **
- ;** return the type of the MMU installed **
- ;*************************************************
- GetMMUType:
- moveq #0,d0
- move.b mulib_MMUType(a6),d0
- rts
- ;ENDFOLD
- ;FOLD GetMMUConfig
- ;*************************************************
- ;** GetMMUConfig **
- ;** read the MMU hardware registers. **
- ;** should be handled with care **
- ;*************************************************
- GetMMUConfig:
- move.l #mcf_len,d0
- bsr AllocContextMem ;get memory for the configuration
- beq.s .exit
-
- move.l d0,-(a7)
- move.l d0,a0
- jsr mulib_ReadConfig(a6) ;fill in the MMU configuration
- move.l (a7)+,d0
- .exit:
- rts
- ;ENDFOLD
- ;FOLD ReleaseMMUConfig
- ;*************************************************
- ;** ReleaseMMUConfig **
- ;** release the MMU information **
- ;*************************************************
- ReleaseMMUConfig:
- move.l a1,d0
- beq.s .noconfig
- bsr FreeContextMem
- .noconfig:
- rts
- ;ENDFOLD
-
-
-
- section main_data,data
- ;FOLD Strings
- xdef MMUName
- MMUName: dc.b "mmu.library",0
- UtilityName: dc.b "utility.library",0
- ExpansionName: dc.b "expansion.library",0
- MC68040Name: dc.b "68040.library",0
- MC68060Name: dc.b "68060.library",0
- dc.b "$VER: "
- IDString: dc.b "mmu "
- TextVersion
- dc.b " "
- TextDate
- dc.b " (c) 1998 The MMU.lib development group, THOR",$0a,$0d,0
-
- ;ENDFOLD
- ;
-